home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * File: kernserv/i386/spl_lock.h
- *
- * Multiprocessor safe simple lock with spl support.
- *
- * This implementation is actually machine independent; it is
- * in the nrw directory to keep it out of the 3.0 release. Post
- * 3.0 this file should probably be in kernserv/spl_lock.h.
- *
- * HISTORY
- * 29-Jan-92 Doug Mitchell at NeXT
- * Created.
- */
-
- #ifndef _KERNSERV_I386_SPL_LOCK_
- #define _KERNSERV_I386_SPL_LOCK_
-
- #import <mach/machine/simple_lock.h>
- #import <bsd/machine/spl.h>
- #import <kernserv/kalloc.h>
-
- /*
- * Encapsulation of a simple lock and its associated IPL. On a multi,
- * every instance of spln() needs to be paired with a simple_lock() in
- * to provide protection from accesses by other CPUs. The spl_lock_t type
- * provides a means of associating an instance of simple_lock with
- * the IPL which must be set to provide adequate protection.
- */
- typedef struct {
- simple_lock_data_t lock;
- unsigned min_ipl;
- } spl_lock_t;
-
- /*
- * Allocate and free spl_lock_t's.
- */
- static inline spl_lock_t *
- spl_lock_alloc()
- {
- return ((spl_lock_t *)kalloc(sizeof(spl_lock_t)));
- }
-
- static inline void
- spl_lock_free(spl_lock_t *lock)
- {
- kfree(lock, sizeof(spl_lock_t));
- }
-
- /*
- * Initialize an spl_lock_t.
- */
- static inline void
- spl_lock_init(spl_lock_t *lock, unsigned min_ipl)
- {
- simple_lock_init(&lock->lock);
- lock->min_ipl = min_ipl;
- }
-
- /*
- * Set ipl to appropriate level and acquire lock. Returns an spl to be
- * used subsequently with spl_unlock().
- */
- static inline unsigned
- spl_lock(spl_lock_t *lock)
- {
- unsigned rtn;
-
- if(curipl() >= lock->min_ipl) {
- /*
- * Don't have to change ipl; just get current value.
- */
- rtn = curipl();
- }
- else {
- rtn = spln(ipltospl(lock->min_ipl));
- }
- simple_lock(&lock->lock);
- return rtn;
- }
-
- /*
- * Release lock, return to previous spl.
- */
- static inline void
- spl_unlock(spl_lock_t *lock, unsigned new_spl)
- {
- simple_unlock(&lock->lock);
- splx(new_spl);
- }
-
- /*
- * Version of thread_sleep() using spl_lock_t instead of simple_lock_t.
- * Used while holding lock and about to sleep.
- */
- static inline void
- spl_lock_thread_sleep(
- int event,
- spl_lock_t *lock,
- boolean_t interruptible,
- unsigned new_spl)
- {
- void thread_sleep();
-
- thread_sleep(event, &lock->lock, interruptible);
- splx(new_spl);
- }
-
- #endif _KERNSERV_I386_SPL_LOCK_
-